import {
  cloneDeep,
  fill,
  isArray,
  isEmpty,
  isNaN,
  isObject,
  isPlainObject,
  isString
} from 'lodash-es';

/**
 * 检测参数值是否是有效的，以下参数值将被视为是无效的：
 * - 自身没有任何可枚举数据的对象
 * - 空字符串
 * - null、undefined
 * - NaN
 * @param {*} value 待验证的参数值
 * @return {boolean} 该参数值是否有效
 */
export function isValidValue(value: any): boolean {
  if (isPlainObject(value) || isString(value)) {
    return !isEmpty(value);
  }
  if (isArray(value)) return value.length > 0;
  return value !== null && value !== undefined && !Number.isNaN(value);
}

/**
 * 格式化参数对象，将空数据从参数对象中移除
 *
 * @param {object} params - 对象
 * @returns {object} 干净对象
 */
export function cleanParams<T>(params: T) {
  const newParams = cloneDeep(params);
  // eslint-disable-next-line guard-for-in
  for (const name in newParams) {
    const value = newParams[name];
    if (!isValidValue(value)) {
      delete newParams[name];
    }
  }
  return newParams;
}
// 创建一个标识码
export function createUnique() {
  const now = new Date();
  return (
    // eslint-disable-next-line prefer-template
    'jc-' +
    now.getFullYear() +
    fill([now.getMonth() + 1], 2) +
    fill([now.getDate()], 2) +
    fill([now.getHours()], 2) +
    fill([now.getMinutes()], 2) +
    fill([now.getSeconds()], 2) +
    fill([now.getMilliseconds()], 3) +
    Math.random().toFixed(20).substring(2)
  );
}
/**
 * 将对象中所有 key 转换为指定命名格式
 *
 * @param data 需要转换的对象
 * @param formatter 命名格式化方法
 */
export const formatObjectKeys = <T = string, R = string>(
  data: unknown,
  formatter: (arg0: T) => R
): unknown => {
  if (isArray(data)) {
    return data.map((item) => formatObjectKeys(item, formatter));
  }
  if (isObject(data)) {
    return Object.fromEntries(
      Object.entries(data).map(([k, v]) => [formatter(k as T), formatObjectKeys(v, formatter)])
    );
  }
  return data;
};

/**
 * 格式化金额
 * @param price string
 * @returns '0.00'
 */
export const formatPrice = (price: string) => {
  if (isNaN(Number(price))) return '0.00';
  return Number(price).toLocaleString(undefined, {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  });
};

/**
 * 转换px为rem
 *
 * @param px number
 * @returns '0rem'
 */
export const px2rem = (px: number) => `${px / 16}rem`;

/**
 * 啥都不干
 *
 * 不想写那么多地方...
 *
 * 而且在某些情况下需要保证相同引用
 */
// eslint-disable-next-line @typescript-eslint/no-empty-function
export const noop = () => {};
export const promiseNoop = () => {
  return Promise.resolve();
};
/**
 * 获得时间戳
 *
 * @param seconds 增加的秒数
 */
export const getTimestamp = (seconds = 0) => Date.now() + seconds * 1000;

/**
 * 将number转换为千分位string
 */
export const formatNumberToThousandthString = (number: number | string) =>
  number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
/**
 * 验证是否在微信环境中
 * @returns {boolean}
 */
export function isWeChat() {
  return isInNavigator('micromessenger');
}
/**
 * 判断浏览器的user-agent信息是否包含字符
 * @param vg {string}
 * @returns {boolean}
 */
export function isInNavigator(vg: string) {
  if (typeof navigator === 'undefined') {
    return false;
  }
  if (typeof vg === 'undefined') {
    return false;
  }
  const agent = navigator.userAgent.toLowerCase();
  return agent.indexOf(vg.toLowerCase()) > -1;
}
